/***************************************************************************
 *   This file is part of KLabeler                                         *
 *   Copyright (C) 2010 by Luca Bellonda                                   *
 *   lbellonda _at_ gmail.com                                              *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#define SCANV(index,collection) for( int index = 0 ; index < collection->size(); index++)
#define GETV(index,type,var,collection) type *var = collection->at(index);

#include "AddTags.h"
#include "ui_AddTags.h"
#include <QCloseEvent>
#include <QStringListModel>
#include <QTableWidgetItem>
#include <QListWidgetItem>
#include <QResizeEvent>
#include "KLabelerApplication.h"
#include "Utility.h"

#define TAG_COLUMNS (2)

AddTags::AddTags(klabeler::KLabelerApplication *newApplication, QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::AddTags)
{
    _application = newApplication ;
    ui->setupUi(this);
    refineUI();

}

AddTags::~AddTags()
{
    TagProfile::deleteProfiles(_profiles);
    _profiles = NULL ;
    delete ui;
}

void AddTags::refineUI()
{
    _tagsCompleter = new QCompleter(this);
    _tagsCompleter->setCaseSensitivity(Qt::CaseInsensitive);
    ui->chooseTag->setCompleter(_tagsCompleter);
    ui->chooseTag->setEditable(true);
    ui->tableTags->setColumnCount(TAG_COLUMNS);
    ui->tableTags->horizontalHeader()->setVisible(false);
    ui->tableTags->verticalHeader()->setVisible(false);
    ui->tableTags->setShowGrid(false);
    ui->addTagButton->setEnabled(false);
    showOtherTags(false);
}

void AddTags::resizeEvent(QResizeEvent * event)
{
    QSize size = ui->tableTags->size();
    int colWidth = (size.width() / TAG_COLUMNS) - 5 * TAG_COLUMNS;
    for (int i = 0 ; i < TAG_COLUMNS ; i++) {
        ui->tableTags->setColumnWidth(i, colWidth);
    }
}

void AddTags::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void AddTags::setTargetResource(const QString &resourcePath)
{
    _resource = resourcePath;
    ui->resourceName->setText(resourcePath);
}

void AddTags::closeEvent(QCloseEvent * event)
{
    _resource = "" ;
    event->accept();
}

void AddTags::cleanData()
{
    ui->chooseTag->clear();
}

void AddTags::go()
{
    _loadingData = true;
    // load current profiles
    cleanData();
    loadAllTags();
    loadResourceTags();
    loadProfileTag();
    loadLastUsedTags();
    loadProfiles();
    showOtherTags(false);
    ui->addTagButton->setEnabled(false);
    _loadingData = false;
    show();
}

void AddTags::showEvent(QShowEvent * event)
{
    if (isVisible()) {
        if (ui->chooseTag->currentText().length() == 0) {
            showOtherTags(false);
        }
    }
}

void AddTags::loadLastUsedTags()
{
    QStringList tags = _application->getConfigurationManager()->getLastUsedTags();
    foreach(QString tag, tags) {
        ui->recentlyUsed->addItem(tag, tag);
    }
}

void AddTags::loadAllTags()
{
    _allTags = _application->getNepomukManager()->getAllTags();
    QStringListModel *model = new QStringListModel();
    model->setStringList(_allTags);
    _tagsCompleter->setModel(model);
}

void AddTags::loadResourceTags()
{
    ui->tableTags->clear();
    _currentlyAssignedTags = _application->getNepomukManager()->getTagsOfResource("file://" + _resource);
    foreach(QString tag, _currentlyAssignedTags) {
        Utility::addTagToSet(ui->tableTags, tag);
    }
}

void AddTags::loadProfileTag()
{
    QString tagProfile = "";
    bool isFirst = true ;
    foreach(QString tag, _currentProfileTags) {
        if (isFirst) {
            isFirst = false;
        } else {
            tagProfile.append(", ");
        }
        tagProfile.append(tag);
    }
    ui->currentProfileTags->setText(tagProfile);
}

void AddTags::on_addTagButton_clicked()
{
    QString text = ui->chooseTag->currentText() ;
    addTagToSet(text);
    loadOtherTags(text);
    //ui->chooseTag->clearEditText();
}

void AddTags::on_chooseTag_editTextChanged(const QString & text)
{
    showOtherTags(false);
    ui->addTagButton->setEnabled(text.length() > 0);
}

void AddTags::loadOtherTags(const QString &tag)
{
    QStringList companionTags = _application->getConfigurationManager()->getCompanionTags(tag);
    ui->listCompanionTags->clear();
    if (companionTags.size() > 0) {
        foreach(QString tag, companionTags) {
            QListWidgetItem *newItem = new QListWidgetItem(tag);
            newItem->setCheckState(Qt::Unchecked);
            ui->listCompanionTags->addItem(newItem);
        }
        showOtherTags(true);
    }
}


QStringList AddTags::getConfirmedTags()
{
    QStringList confirmedTags ;
    QTableWidget *table = ui->tableTags ;
    int rows = table->rowCount();
    for (int row = 0 ; row < rows ; row ++) {
        for (int col = 0 ; col < TAG_COLUMNS ; col++) {
            QTableWidgetItem *item = table->item(row, col);
            if (NULL != item) {
                if (item->checkState() == Qt::Checked) {
                    QString value = item->text() ;
                    confirmedTags.append(value);
                }
            }
        }
    }
    return confirmedTags;
}

void AddTags::addTagToSet(const QString &tag)
{
    Utility::addTagToSet(ui->tableTags, tag);
}

void AddTags::showOtherTags(const bool isShow)
{
    if (ui->labelToghether->isVisible() != isShow) {
        ui->labelToghether->setVisible(isShow);
        ui->listCompanionTags->setVisible(isShow);
        if (!isShow) {
            ui->listCompanionTags->reset();
        }
    }
}

void AddTags::setCurrentProfileTags(QStringList currentProfileTags)
{
    _currentProfileTags = currentProfileTags ;
}

void AddTags::on_tableTags_itemClicked(QTableWidgetItem * item)
{

}

void AddTags::on_listCompanionTags_itemClicked(QListWidgetItem * item)
{
    if (item->checkState() == Qt::Checked) {
        addTagToSet(item->text());
        ui->listCompanionTags->takeItem(ui->listCompanionTags->row(item));
        delete item;
    }
}

void AddTags::on_addTagsFromCurrentProfile_clicked()
{
    foreach(QString tag, _currentProfileTags) {
        addTagToSet(tag);
    }
}

//TODO:        elimina tag presenti non confermati su OK

void AddTags::on_cmdOK_clicked()
{
    QStringList confirmedTags = Utility::normalizeTags(getConfirmedTags());

    bool isOk = true ;
    if (!saveTags(confirmedTags, _currentlyAssignedTags)) {
        isOk = false;
    }
    if (!saveTagSetConfiguration(confirmedTags)) {
        isOk = false;
    }
    if (!isOk) {
        Utility::error(this, i18n("Error saving profile."));
    }
    close();
}

void AddTags::on_cmdCancel_clicked()
{
    close();
}

bool AddTags::saveTags(QStringList &confirmedTags, QStringList &currentlyAssignedTags)
{
    return _application->getNepomukManager()->saveTags(_resource, confirmedTags, currentlyAssignedTags);
}

bool AddTags::saveTagSetConfiguration(const QStringList &confirmedTags)
{
    return _application->getConfigurationManager()->saveTagSetConfiguration(confirmedTags);
}

void AddTags::on_recentlyUsed_currentIndexChanged(int index)
{
    QString text = ui->recentlyUsed->itemText(index);
    addTagToSet(text);
}

void AddTags::loadProfiles()
{
    _profiles = _application->getConfigurationManager()->getProfilesListLight();
    if (NULL != _profiles) {
        int size = _profiles->size();
        for (int i = 0; i < size; i++) {
            TagProfile* profile = _profiles->at(i) ;
            ui->profiles->addItem(profile->getName(), profile->getId());
        }
        ui->profiles->setEnabled(true);
    } else {
        ui->profiles->setEnabled(false);
    }
}

void AddTags::on_profiles_currentIndexChanged(int index)
{
    if (_loadingData) {
        return ;
    }
    if (index >= 0) {
        QString id = ui->profiles->itemData(index).toString();
        if (!id.isEmpty()) {
            bool isOk = false;
            QStringList tags = _application->getConfigurationManager()->getProfileTags(id, isOk);
            if (!isOk) {
                Utility::error(this, i18n("Error retrieving profile informations."));
            }
            foreach(QString tag, tags) {
                addTagToSet(tag);
            }
        }
    }
}

